/**
* @version:1.0
* @author kevinnan.org.cn  2018212114@mail.hfut.edu.cn
* @date 2020/7/24
* @Content:灰度变换常用函数实现
*/

#include "gray_transform.hpp"

cv::Mat graytransform::gammaTransform(cv::Mat originImage, float gamma, int constant) {
	cv::Mat transformedImage = originImage.clone();

	originImage.convertTo(originImage, CV_32FC1);
	auto tempImage = originImage / 255;

	cv::pow(tempImage, gamma, transformedImage);
	transformedImage *= constant;
	transformedImage *= 255;
	transformedImage.convertTo(transformedImage, 0);
    return transformedImage;
}


cv::Mat graytransform::imageReverse(cv::Mat originImage){
	auto tempImage = 255 - originImage;
	return tempImage;
}


cv::Mat graytransform::logarithmTransform(cv::Mat originImage, int constant){
	originImage.convertTo(originImage, CV_32FC1);
	auto tempImage = originImage.clone();

	tempImage /= 255;
	cv::log(originImage + 1, tempImage);
	tempImage *= constant;
	tempImage *= 255;
	tempImage.convertTo(tempImage, 0);
	return tempImage;
}


void graytransform::drawHistogram(cv::Mat originImage, string imgName){
	//统计像素值出现的次数
	std::vector<int> countPixel(256, 0);

	//统计灰度值出现次数
	for(int i = 0; i < originImage.rows; i++){
		uchar* data = originImage.ptr<uchar>(i);
		for(int j = 0; j < originImage.cols; j++){
			countPixel[data[j]]++;
		}
	}

	int size = 256;
	int maxValue = *max_element(countPixel.begin(), countPixel.end());
	cout<<"max_element"<<maxValue<<endl;
	cv::Mat histgramVisiablize(countPixel.size(), countPixel.size(), CV_8U, cv::Scalar(0));

	for(int i = 0; i < countPixel.size(); i++){
		cv::line(histgramVisiablize, cv::Point(i, size-1), 
				 cv::Point(i, size-(countPixel[i]*(size*0.9)/maxValue)), cv::Scalar(255));
	}

	// cv::imwrite("../../images/" + imgName + "_hist.jpg", histgramVisiablize);
	// cv::imshow(imgName, histgramVisiablize);

}


cv::Mat graytransform::equalizeHistogram(cv::Mat originImage){
	float sumPixel = originImage.rows * originImage.cols;
	cout<<"rows:"<<originImage.rows<<"\t"<<"cols:"<<originImage.cols<<endl;
	cout<<"sumPixel:"<<sumPixel<<endl;

	int size = 256;

	auto tempImage = originImage.clone();
	//统计像素值出现的次数
	std::vector<int> countPixel(256, 0);
	//直方图灰度分布概率
	std::vector<float> rowProb;
	//直方图均衡变换后得到的值
	std::vector<int> transformValue;
	//直方图均衡结果
	std::vector<int> equalizeResult(256, 0);

	//统计灰度值出现次数
	for(int i = 0; i < originImage.rows; i++){
		uchar* data = originImage.ptr<uchar>(i);
		for(int j = 0; j < originImage.cols; j++){
			countPixel[data[j]]++;
		}
	}

	//计算灰度值概率
	for(auto iter = countPixel.begin(); iter != countPixel.end(); iter++){
		rowProb.push_back(*iter / sumPixel);
	}

	//计算直方图均衡结果
	for(int i = 0; i < rowProb.size(); i++){
		int s = 0;
		for(int j = 0; j <= i; j++){
			s += round(255 * rowProb[j]);
		}
		if(s > 255)
			s = 255;
		transformValue.push_back(s);
	}

	//进行直方图均衡变换
	for(int i = 0; i < tempImage.rows; i++){
		for(int j = 0; j < tempImage.cols; j++){
			tempImage.at<uchar>(i, j) = transformValue[tempImage.at<uchar>(i, j)];
		}
	}

	//drawHistogram(originImage, "originImage");
	// cv::imwrite("../../images/histogramResult3.jpg", tempImage);
	// drawHistogram(tempImage, "tempImage_3");
	return tempImage;
}
